package cn.his.medical.pacshism.view;

import android.content.Context;
import android.database.DataSetObserver;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.Nullable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.FrameLayout;

import java.util.LinkedList;

/**
 * @类名 BannerView
 * @描述 自定义卡片轮播
 * @作者 xiewei
 * @创建时间 2018/3/6 9:05
 */
public class BannerView extends FrameLayout {
    private ViewPager viewPager;
    private static int MAX_COUNT = 100000;
    private BaseAdapter adapter;
    private ViewPagerAdapter pagerAdapter;

    private long BANNER_DURING = 2000;

    private OnBannerChangeListener onBannerChangeListener;

    private DataSetObserver dataSetObserver = new DataSetObserver() {
        @Override
        public void onChanged() {
            onDataChanged();
        }

        @Override
        public void onInvalidated() {
            onDataChanged();
        }
    };

    private Handler handler = new Handler(Looper.getMainLooper());

    public BannerView(Context context) {
        this(context, null);
    }

    public BannerView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public BannerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        viewPager = new ViewPager(context);
        addView(viewPager, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        registerListener();
    }

    private void registerListener() {
        viewPager.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                switch (motionEvent.getAction()) {
                    case MotionEvent.ACTION_UP:
                        // 开始图片滚动
                        performClick();
                        startBanner();
                        break;
                    default:
                        // 停止图片滚动
                        stopBanner();
                        break;
                }
                return false;
            }
        });
        viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                if (adapter == null) return;
                int adapterCount = adapter.getCount();
                if (onBannerChangeListener != null) {
                    onBannerChangeListener.onBannerChanged(position % adapterCount);
                }
            }
        });
    }

    private Runnable bannerTask = new Runnable() {
        @Override
        public void run() {
            if (adapter == null) return;
            int currentPos = viewPager.getCurrentItem();
            if (currentPos == MAX_COUNT - 1) {
                currentPos = 0;
            } else {
                currentPos++;
            }
            viewPager.setCurrentItem(currentPos);
            startBanner();
        }
    };

    public void setBannerDuring(long time) {
        stopBanner();
        this.BANNER_DURING = time;
        startBanner();
    }

    public void setAdapter(BaseAdapter adapter) {
        stopBanner();
        if (this.adapter != null) {
            this.adapter.unregisterDataSetObserver(dataSetObserver);
        }
        this.adapter = adapter;
        this.adapter.registerDataSetObserver(dataSetObserver);
        this.adapter.notifyDataSetChanged();
        startBanner();
    }

    private void startBanner() {
        handler.postDelayed(bannerTask, BANNER_DURING);
    }

    private void stopBanner() {
        handler.removeCallbacks(bannerTask);
    }

    private void onDataChanged() {
        int count = adapter.getCount();
        if (count == 0) return;
        int index = (MAX_COUNT / 2) % count;
        pagerAdapter = new ViewPagerAdapter();
        viewPager.setAdapter(pagerAdapter);
        viewPager.setCurrentItem(MAX_COUNT / 2 - index, false);
    }

    public void setOnBannerChangeListener(OnBannerChangeListener onBannerChangeListener) {
        this.onBannerChangeListener = onBannerChangeListener;
    }

    public interface OnBannerChangeListener {
        void onBannerChanged(int pos);
    }

    private class ViewPagerAdapter extends PagerAdapter {

        private LinkedList<View> cacheList = new LinkedList<>();

        @Override
        public int getCount() {
            return MAX_COUNT;
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            View view = (View) object;
            container.removeView(view);
            cacheList.push(view);
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            if (adapter == null) return null;
            int targetPosition = position % adapter.getCount();
            View view;
            if (cacheList.size() != 0) {
                view = adapter.getView(targetPosition, cacheList.pollFirst(), container);
            } else {
                view = adapter.getView(targetPosition, null, container);
            }
            container.addView(view);
            return view;
        }
    }
}
